﻿@* Generator: WebPagesHelper *@

@using System.Globalization
@using System.Text
@using System.Web.WebPages.Scope
@using Microsoft.Internal.Web.Utils
@using Resources;
@functions {
    internal static readonly object _bitlyApiKey = new object();
    internal static readonly object _bitlyLogin = new object();
    private static readonly Lazy<IEnumerable<LinkShareSite>> _allSites = new Lazy<IEnumerable<LinkShareSite>>(() =>
        from site in (LinkShareSite[])Enum.GetValues(typeof(LinkShareSite))
#pragma warning disable 0618
        where site != LinkShareSite.All
#pragma warning restore 0618
        select site
    );

    public static string BitlyApiKey {
        get {
            return ScopeStorage.CurrentScope[_bitlyApiKey] as string;
        }

        set {
            if (value == null) {
                throw new ArgumentNullException("value");
            }
            ScopeStorage.CurrentScope[_bitlyApiKey] = value;
        }
    }

    public static string BitlyLogin {
        get {
            return ScopeStorage.CurrentScope[_bitlyLogin] as string;
        }

        set {
            if (value == null) {
                throw new ArgumentNullException("value");
            }
            ScopeStorage.CurrentScope[_bitlyLogin] = value;
        }
    }

    private static string GetShortenedUrl(string pageLinkBack) {
        if (BitlyLogin.IsEmpty() || BitlyApiKey.IsEmpty()) {
            return pageLinkBack;
        }
        string encodedPageLinkBack = HttpUtility.UrlEncode(pageLinkBack);
        string key = "Bitly_pageLinkBack_" + BitlyApiKey + "_" + encodedPageLinkBack;
        string shortUrl = WebCache.Get(key) as string;
        if (shortUrl != null) {
            return shortUrl;
        }

        string bitlyReq = "http://api.bit.ly/v3/shorten?format=txt&longUrl=" + encodedPageLinkBack + "&login=" + BitlyLogin + "&apiKey=" + BitlyApiKey;
        try {
            shortUrl = GetWebResponse(bitlyReq);
        }
        catch (WebException) {
            return pageLinkBack;
        }
        if (shortUrl != null) {
            WebCache.Set(key, shortUrl);
            return shortUrl;
        }
        return pageLinkBack;
    }

    private static string GetWebResponse(string address) {
        WebRequest request = WebRequest.Create(address);
        request.Method = "GET";
        request.Timeout = 5 * 1000; //5 seconds
        using (var response = (HttpWebResponse)request.GetResponse()) {
            if (response.StatusCode != HttpStatusCode.OK) {
                return null;
            }
            using (Stream stream = response.GetResponseStream()) {
                using (MemoryStream memStream = new MemoryStream()) {
                    stream.CopyTo(memStream);
                    // Review: Should we use the ContentEncoding from response?
                    return Encoding.UTF8.GetString(memStream.ToArray());
                }
            }
        }
    }

    /// <summary>
    /// Returns an ordered list of LinkShareSite based on position of "All" parameter occurs in the list.
    /// </summary>
    /// <remarks>
    /// The LinkShareSite is accepted as a params array.
    /// In the event that no value is provided or the LinkShareSite.All is the first param, we display all the sites in the order they appear in the enum.
    /// If not, the items we look for the first occurence of LinkShareSite.All in the array. 
    /// The items that appear before this appear in the order they are specified. The All is replaced by all items in the enum that were not already specified by the user 
    /// in the order they appear in the enum.
    /// e.g.  sites = [] { Twitter, Facebook, Digg, All }
    /// Would result in returning {Twitter, Facebook, Digg, Delicious, Reddit, StumbleUpon} 
    /// </remarks>
    internal static IEnumerable<LinkShareSite> GetSitesInOrder(LinkShareSite[] linkSites) {
        var allSites = _allSites.Value;
        if (linkSites == null || !linkSites.Any() || linkSites.First() == LinkShareSite.All) {
            // Show all sites
            return allSites;
        }
        var result = linkSites.TakeWhile(c => c != LinkShareSite.All).ToList();
        if (result.Count != linkSites.Length) {
            return Enumerable.Concat(result, allSites.Except(result));
        }
        else {
            return result;
        }
    }

    private static void ConstructPageLinkBack(ref string pageLinkBack, out string shortenedUrl) {
        HttpContext context = HttpContext.Current;
        if ((pageLinkBack == null) && (context != null)) {
            pageLinkBack = context.Request.Url.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.Unescaped);
        }
        shortenedUrl = GetShortenedUrl(pageLinkBack);
    }
}

@helper GetHtml(string pageTitle,
    string pageLinkBack = null,
    string twitterUserName = null,
    string additionalTweetText = null,
    params LinkShareSite[] linkSites) {

    if (pageTitle.IsEmpty()) {
        throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, CommonResources.Argument_Cannot_Be_Null_Or_Empty, "pageTitle"), "pageTitle");
    }

    string shortenedUrl;
    ConstructPageLinkBack(ref pageLinkBack, out shortenedUrl);

    pageLinkBack = HttpUtility.UrlEncode(pageLinkBack);
    shortenedUrl = HttpUtility.UrlEncode(shortenedUrl);
    pageTitle = HttpUtility.UrlEncode(pageTitle);

    foreach (var site in GetSitesInOrder(linkSites)) {
        switch (site) {
            case LinkShareSite.Delicious:
                <a href="http://delicious.com/save?v=5&amp;noui&amp;jump=close&amp;url=@(shortenedUrl)&amp;title=@(pageTitle)" target="_blank" title="Add to del.icio.us">
                    <img alt="Add to del.icio.us" src="https://delicious.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Add to del.icio.us" /></a>
                break;

            case LinkShareSite.Digg:
                <a href="http://digg.com/submit?url=@(pageLinkBack)&amp;title=@(pageTitle)" target="_blank" title="Digg!">
                    <img alt="Digg!" src="http://digg.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Digg!" /></a>
                break;
            case LinkShareSite.Facebook:
                <a href="http://www.facebook.com/sharer.php?u=@(shortenedUrl)&amp;t=@(pageTitle)" target="_blank" title="Share on Facebook">
                    <img alt="Share on Facebook" src="http://facebook.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Share on Facebook" /></a>
                break;
            case LinkShareSite.Reddit:
                <a href="http://reddit.com/submit?url=@(pageLinkBack)&amp;title=@(pageTitle)" target="_blank" title="Reddit!">
                    <img alt="Reddit!" src="http://www.reddit.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Reddit!" /></a>
                break;
            case LinkShareSite.StumbleUpon:
                <a href="http://www.stumbleupon.com/submit?url=@(pageLinkBack)&amp;title=@(pageTitle)" target="_blank" title="Stumble it!">
                    <img alt="Stumble it!" src="http://stumbleupon.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Stumble it!" /></a>
                break;            
            case LinkShareSite.Twitter:
                string status = String.Empty;
                if (!twitterUserName.IsEmpty()) {
                    status += ", (via @@" + twitterUserName + ")";
                }
                if (!additionalTweetText.IsEmpty()) {
                    status += ' ' + additionalTweetText;
                }
                status = HttpUtility.UrlEncode(status);
                <a href="http://twitter.com/home/?status=@(pageTitle)%3a+@(shortenedUrl)@(status)" target="_blank" title="Share on Twitter">
                    <img alt="Share on Twitter" src="http://twitter.com/favicon.ico" style="border:0; height:16px; width:16px; margin:0 1px;" title="Share on Twitter" />
                </a>
                break;
            default:
                throw new NotSupportedException(String.Format(CultureInfo.CurrentUICulture, HelpersToolkitResources.LinkShareValue_NotSupported, site));                
        }
    }
}